print("----------__add-----------")
local meta_tbl = {
	__add = function(t1, t2)
		local rs = {}

		local len1 = #t1
		local len2 = #t2

		if len1 > len2 then
			len2 = len1
		end

		for i = 1, len2 do
			local a = t1[i] or 0
			local b = t2[i] or 0
			rs[i] = a + b
		end
		return rs
	end,
}

local tbl1 = setmetatable({ 1, 2, 3 }, meta_tbl)
local tbl2 = setmetatable({ 3, 2, 1 }, meta_tbl)
local tbl3 = tbl1 + tbl2
for k, v in ipairs(tbl3) do
	print(k, v)
end

print("----------__index-----------")
local tbl4 = setmetatable({ name = "lua" }, { __index = { age = 20 } })
print(tbl4.age)
local tbl5 = setmetatable({ name = "lua" }, {
	__index = function()
		return 21
	end,
})
print(tbl5.age)

print("----------__newindex-----------")
local tbl6 = setmetatable({ name = "lua" }, {
	__newindex = function(tbl, ...)
		error("Attempt to modify a readonly table", tbl)
	end,
})
tbl6["age"] = 21

print("----------__tostring-----------")
local tbl7 = setmetatable({ name = "lua" }, {
	__tostring = function()
		return "this is a table"
	end,
})
print(tbl7)

print("----------__tocall-----------")
local tbl8 = setmetatable({ name = "lua" }, {
	__call = function(...)
		print("get arg: ", select(2, ...))
		return "this is call func"
	end,
})
print(tbl8(1, 2, 3, 4))
print("----------self-----------")
local t0 = { id = 1 }
function t0:getId()
	return self.id
end
print(t0:getId())

print("----------自索引-----------")
--自引用，将元表的__index指向元表，外表就可以调用元表中的方法
local t1 = { id = 123, name = "tom" }
local t2 = {
	hello = function()
		print("hello")
	end,
}
t2.__index = t2 --必须加上此行不然报错
setmetatable(t1, t2)

t1:hello()
t1.hello()

print("----------类的实例化-----------")
--自己担任元表角色，并且__index指向自己
local userInfo = { id = 123, name = "tom", age = 99 }
userInfo.__index = userInfo

function userInfo:new(obj)
	obj = obj or {}
	setmetatable(obj, self)
	return obj
end

function userInfo:setAge(val)
	self.age = self.age + val
end

local u1 = userInfo
local u2 = u1
print(u1.age, u2.age)
u2:setAge(20)
print(u1.age, u2.age)

-- 生成一个对象
local u3 = userInfo:new({ id = 456 })
print(u3.age)

u3:setAge(100)
print(u3.age)

